#include "parameter.h"
#include "eeprom.h"
#include "main.h"
#if 1
    #include <stdio.h>
    #define PRINTF printf
#else
    #define PRINTF(...)
#endif

const bootloader_t defdata = {.JumpAddress = 0,
                              .JumpToApplication = NULL,
                              .ApplicationAddress = 0x08020000,
                              .DownloadAddress = 0x08040000,
                              .PowerOnCount = 1,
                              .FactoryCRC = 0,
                              .downCRC = 0,
                              .downByteLen = 0,
                              .applCRC = 0,
                              .ParaInitFlag = 0x0001};
bootloader_t btdata;

int32_t ParameterRead32(uint16_t VirtAddress, uint32_t *Data)
{
    uint16_t ret, temp;
    uint32_t d;

    ret = EE_ReadVariable(VirtAddress, &temp);
    if (0 == ret)
    {
        d = temp;
    }
    else if (1 == ret)
    {
        return -1;
    }
    else
    {
        return -2;
    }
    ret = EE_ReadVariable(VirtAddress + 1, &temp);
    if (0 == ret)
    {
        d |= temp << 16;
        *Data = d;
    }
    else if (1 == ret)
    {
        return -3;
    }
    else
    {
        return -4;
    }
    return 0;
}
int32_t ParameterWrite32(uint16_t VirtAddress, uint32_t Data)
{
    uint16_t ret, temp;

    temp = Data;
    ret = EE_WriteVariable(VirtAddress, temp);
    if (0 != ret)
    {
        return -1;
    }
    temp = Data >> 16;
    ret = EE_WriteVariable(VirtAddress + 1, temp);
    if (0 != ret)
    {
        return -2;
    }
    return 0;
}
int32_t ParameterInit(void)
{
    uint16_t ret;
    bootloader_t *p = &btdata;
    bootloader_t *pdef = (bootloader_t *)&defdata;

    /* EEPROM Init */
    PRINTF("EEPROM emulation Init.\n\r");
    ret = EE_Init();
    if (ret != EE_OK)
    {
        PRINTF("KO\n\r");
        Error_Handler();
    }
    ret = EE_ReadVariable(PARAINITFLAG, &p->ParaInitFlag);
    if (0 == ret || 1 == ret)
    {
        if (p->ParaInitFlag != pdef->ParaInitFlag)
        {
            PRINTF("Init default parameters\n\r");
            ret = EE_WriteVariable(POWER_ON_COUNT, pdef->PowerOnCount);
            ret += ParameterWrite32(APPL_ADDR_LWORD, pdef->ApplicationAddress);
            ret += ParameterWrite32(DOWN_ADDR_LWORD, pdef->DownloadAddress);
            ret += EE_WriteVariable(PARAINITFLAG, pdef->ParaInitFlag);
            ret += EE_ReadVariable(POWER_ON_COUNT, &p->PowerOnCount);
            ret += ParameterRead32(APPL_ADDR_LWORD, &p->ApplicationAddress);
            ret += ParameterRead32(DOWN_ADDR_LWORD, &p->DownloadAddress);
            ret += EE_ReadVariable(POWER_ON_COUNT, &p->ParaInitFlag);
            ret += EE_ReadVariable(DOWNDATA_CRC, &p->downCRC);
            ret += ParameterRead32(DOWNBYTELEN_LWORD, &p->downByteLen);
        }
        else
        {
            ret = EE_ReadVariable(POWER_ON_COUNT, &p->PowerOnCount);
            if (0 == ret)
            {
                p->PowerOnCount += 1;
                ret += EE_WriteVariable(POWER_ON_COUNT, p->PowerOnCount);
            }
            ret += EE_ReadVariable(POWER_ON_COUNT, &p->PowerOnCount);
            ret += ParameterRead32(APPL_ADDR_LWORD, &p->ApplicationAddress);
            ret += ParameterRead32(DOWN_ADDR_LWORD, &p->DownloadAddress);
        }
        PRINTF("Power on counter is %u\r\n", p->PowerOnCount);
        p->bootinfo = (project_info_t *)0x08000400;
        p->appinfo = (project_info_t *)(p->ApplicationAddress + 0x400);
        p->downinfo = (project_info_t *)(p->DownloadAddress + 0x400);
    }
    else
    {
        PRINTF("EE_ReadVariable KO. %d\n\r", ret);
        return -1;
    }
    return ret;
}
